Dane - Credit Cards Customers.
Problem - zbadaj którzy klienci są chętni do zrezygnowania z usługi.
Do zadania został użyty model Xgboost.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
import seaborn as sns
plt.style.use('ggplot')
import dalex as dx
import pickle
import xgboost as xgb
from scipy import stats
from scipy.stats import norm
from sklearn.model_selection import train_test_split
import math
import warnings
warnings.filterwarnings('ignore')
np.random.seed(23)
input_df = pd.read_csv('data/preprocessed_dataset.csv')
y = input_df.loc[:,'Attrition']
X = input_df.drop('Attrition', axis='columns')
xgboost = pickle.load(open("xgb_model.p", "rb" ))
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)
explainer = dx.Explainer(xgboost, X_train, y_train, label = "Random Forest")
Preparation of a new explainer is initiated -> data : 7595 rows 24 cols -> target variable : Parameter 'y' was a pandas.Series. Converted to a numpy.ndarray. -> target variable : 7595 values -> model_class : xgboost.sklearn.XGBClassifier (default) -> label : Random Forest -> predict function : <function yhat_proba_default at 0x000002B1872CB280> will be used (default) -> predict function : Accepts pandas.DataFrame and numpy.ndarray. -> predicted values : min = 9.37e-06, mean = 0.841, max = 1.0 -> model type : classification will be used (default) -> residual function : difference between y and yhat (default) -> residuals : min = -0.779, mean = -5.26e-05, max = 0.7 -> model_info : package xgboost A new explainer has been created!
explainer.predict(X_train)[0]
0.9727738
Dla wybranej obserwacji model Xgboost ma wsoką predykcję ok. 98%.
0 - Attrited Customer
1 - Existing Customer
ps = explainer.predict_surrogate(X_train.iloc[0,:], type = "lime")
ps.show_in_notebook()
ps5 = explainer.predict_surrogate(X_train.iloc[29,:], type = "lime")
ps5.show_in_notebook()
#29
ps5 = explainer.predict_surrogate(X_train.iloc[29,:], type = "lime")
ps5.show_in_notebook()
#29
ps5 = explainer.predict_surrogate(X_train.iloc[30,:], type = "lime")
ps5.show_in_notebook()
#30
Pomimo użycia np.random.seed(23) na początku notebooka, przy ponownym wywołaniu okna dostajemy różne wyniki. Prawdopodobieństwo predykcji jest takie samo, inny jest wpływ cech na predykcję lub wartość wpływu na predykcję. Na przykład dla tej samej obserwacji Card_Platinum równe 0 raz jest niebieskie a raz pomarańczowe. Można też zauważyć, że dla dwóch róznych obserwacji (29, 30) Card_Platinum o tej samej wartości może mieć odwrotny pływ a predykcję.
ps4 = explainer.predict_surrogate(X_train.iloc[3,:], type = "lime")
ps4.show_in_notebook()
ps2 = explainer.predict_surrogate(X_train.iloc[1,:], type = "lime")
ps2.show_in_notebook()
Dla obu obserwacji największy udział w predykcji mają Total_Revolving_Bal oraz Total_Trans_Amt. Pierwsza zmienna działa tak samo w obu przypadkach, jednak dla zmiennej Total_Trans_Amt z wykresu mozemy odczytać inne kryteria. Dla obserwacji 3. Total_Trans_Amt > ok. 4700 wpływa na wybór 1 - Existing Customer, a dla obserwacji 1. Total_Trans_Amt > 3906 wpływa wybór 0 - Attrited Customer.
Ustalenie konkretnego seeda nie pozwala mi na zachowanie jednakowych wyników przy kolejnych wywyołaniach. Cieżko zrozumieć mi wpływ zmiennych na predykcję. Wykres wygląda podobnie do dekompozycji Shapley values lecz w nim pokazana była także bazowa predykcja. Zamiast tego LIME pokazuje nam wniosek z wykresu Shapley values, czyli prawdopodobieństwo predykcji. Zadziwiające są dla mnie obserwację 1. i 3. które dla Total_Trans_Amt równego 4006 i 4768 mają zupełnie inny wpływ na predykcję.